/*************************************************************************
 *                                                                       *
 * This file is part of the DogosFrame distribution.  For full copyright *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 *                                                                       *
 *************************************************************************/

#ifndef DOGOS_include_tbox_DogosManager_h
#define DOGOS_include_tbox_DogosManager_h

//COMMON headers
#include "COMMON/base/Common.h"
#include "COMMON/tbox/PIO.h"
#include "COMMON/tbox/StartupShutdownManager.h"

namespace DOGOS
{

/**
 * @brief Utility for managing startup and shutdown of DOGOS objects
 * and for managing the maximum number of patch data components allowed.
 *
 * The startup/shutdown mechanism in FreeMAPsManager is used to manage the
 * allocation and deallocation of certain memory, particularly static data
 * that must exist during the full extent of a run or for the full extent
 * of a single problem within a run.  The specific data that is controlled
 * by this mechanism is managed using the StartupShutdownManager.
 *
 * The four steps of the startup/shutdown mechanism are:
 *
 * <ul>
 * <li> initialize -- called at the start of a program after MPI is
 *      initialized but befor any other DOGOS objects are used.
 * <li> startup -- called to begin a problem-specific segment of the code.
 * <li> shutdown -- called at the end of a problem-specific segment of the
 *                  code.  Shuts down and deallocates everything that was
 *                  started and allocated by startup.
 * <li> finalize -- called at the end of a program right before MPI is
 *                  finalized.
 * </ul>
 *
 * The startup and shutdown functions may be called multiple times within a
 * run, in order to allow for the execution of more than one problem within one
 * program.  Initialize and finalize must be called exactly once in a single
 * run.
 *
 * Additionally this class manages static data that controls the maximum
 * number of patch data components that can be allowed.
 *
 * @see tbox::StartupShutdownManager
 */

class DogosManager
{
public:

    /**
     * @brief Startup of the DOGOS package.
     *
     * This function invokes startup for any classes that implement the
     * startup callback interface through StartupShutdownManager.
     * This function may be invoked more than once in a process if
     * solving multiple DOGOS problems.
     *
     * @pre s_initialized
     * @pre !s_started
     */
    static inline void
    startup();

    /**
     * @brief Shutdown the DOGOS package.
     *
     * This function invokes shutdown for any classes that implement the
     * startup callback interface through StartupShutdownManager.
     * This function may be invoked more than once in an process if
     * solving multiple DOGOS problems.
     *
     * @pre s_initialized
     * @pre s_started
     */
    static inline void
    shutdown();

    /**
     * @brief Final cleanup of the DOGOS package.
     *
     * This function should be invoked ONLY ONCE at the end of a process
     * to complete the cleanup of DOGOS memory allocations and
     * any other cleanup tasks.  IEEE assertion handlers and DOGOS I/O
     * will be finalized, as well as data for any classes that implement
     * the finalize callback interface through StartupShutdownManager.
     *
     * After this function is called, the only thing that should occur before
     * exiting the program is a call to 
     *
     * This function should be invoked only once.
     *
     * @pre s_initialized
     */
    static inline void
    finalize();

    /**
     * @brief Returns true if FreeMAPsManager has been initialized.
     */
    static inline bool
    is_initialized();

    /**
     * @brief Returns true if FreeMAPsManager has been started.
     */
    static inline bool
    is_started();

    /**
     * @brief Return maximum number of patch data entries supported by DOGOS.
     *
     * The value is either the default value (256) or the value set by calling
     * the set_max_num_patch_data_entries() function.
     */
    static inline int
    get_max_num_patch_data_entries();

public:

    /**
     * @brief Initial setup of the DOGOS package.
     *
     * This function should be invoked ONLY ONCE at the start of a process
     * to initialize DOGOS and AFTER MPI is initialized (if used) by a
     * call to one of the init routines.
     *
     * This function initializes IEEE expection handlers and DOGOS I/O, as
     * well as data for any classes that implement the initialize callback
     * interface through StartupShutdownManager.
     *
     * @param[in] initialize_IEEE_assertion_handlers (defaults to true)
     *
     * @pre !s_initialized
     */
    static void
    initialize(
        bool initialize_IEEE_assertion_handlers = true);

    /**
     * @brief Set maximum number of patch data entries supported by DOGOS.
     *
     * The maximum number will be set to the maximum of the current value and
     * the argument value.
     *
     * Note that this routine cannot be called anytime after the max patch
     * data entries value has been accessed via the
     * get_max_num_patch_data_entries() function, neither by the user nor
     * internally within DOGOS.  Typically, the first internal access of this
     * value occurs whenever any objects related to the patch hierarchy or
     * variables are created.
     *
     * @pre s_max_patch_data_entries_accessed
     */
    static void
    set_max_num_patch_data_entries(
        int maxnum);

private:

    /*
     * Flag indicating FreeMAPsManager has been initialized.
     */
    static bool s_initialized;

    /*
     * Flag indicating startup has occured.
     */
    static bool s_started;

    /*
     * Maximum number of patch data components allowed.
     */
    static int s_max_patch_data_entries;

    /*
     * Flag telling whether maximum number of patch data components has
     * been accessed.
     */
    static bool s_max_patch_data_entries_accessed;

private:

    DISALLOW_COPY_AND_ASSIGN (DogosManager);
};

}

#include "COMMON/tbox/DogosManager.inl"

#endif
